package org.FaPe3D.core.files
{
	import flash.utils.clearInterval;
	import flash.utils.clearTimeout;
	import flash.utils.setInterval;
	import flash.utils.setTimeout;
	
	import org.papervision3d.events.FileLoadEvent;
	
	public class FPLoaderInfo
	{
		private static var _materialList:Array = new Array();
		private static var _allMaterialsLoaded:Function = null;
		private static var _timeoutCallBack:uint = 0;
		//
		public var loaded:Boolean = false;
		public var error:Boolean = false;
		public var bytesLoaded:Number = 0;
		public var bytesTotal:Number = 0;
		public var material:* = null;
		private var interval:Number = 0;
		
		public function FPLoaderInfo(_material:*)
		{
			// setup
			material = _material;
			
			// events
			material.addEventListener(FileLoadEvent.LOAD_COMPLETE, _onLoadComplete);
			material.addEventListener(FileLoadEvent.LOAD_ERROR, _onLoadError);
			material.addEventListener(FileLoadEvent.LOAD_PROGRESS, _onProgress);
			material.addEventListener(FileLoadEvent.SECURITY_LOAD_ERROR, _onLoadError);
			
			clearInterval(interval);
			interval = setInterval(checkLoading, 100);
			// setTimeout(function(){trace(material.loaded);}, 4000);
		}
		
		private function checkLoading():void
		{
			if(material.loaded)
			{
				clearInterval(interval);
				//
				_onLoadComplete(new FileLoadEvent(FileLoadEvent.LOAD_COMPLETE));
			}
		}
		
		private static function findMaterial(_material:*):Boolean
		{
			var b:Boolean = false;
			//
			for(var i:Number =0; i<_materialList.length; i++)
			{
				if(_material.url == _materialList[i].material.url)
				{
					b = true;
					break;
				}
			}
			
			return b;
		}
		
		
		private function _onLoadComplete(e:FileLoadEvent):void
		{
			clearInterval(interval);
			//
			loaded = true;
			//
			checkMaterialsLoading();
		}
		
		private function _onLoadError(e:FileLoadEvent):void
		{
			clearInterval(interval);
			//
			error = true;
			//
			checkMaterialsLoading();
		}
		
		private function _onProgress(e:FileLoadEvent):void
		{
			bytesLoaded = e.bytesLoaded;
			bytesTotal = e.bytesTotal;
		}
		
		public static function add(_material:*):void
		{
			_materialList.push( new FPLoaderInfo(_material) );
		}
		
		/*public static function add(_material:*):void
		{
			if( !findMaterial(_material) )
			{
				_materialList.push( new FPLoaderInfo(_material) );
			}else
			{
				clearTimeout(_timeoutCallBack);
				_timeoutCallBack = setTimeout(checkMaterialsLoading, 250);
			}
		}*/
		
		public static function getMaterialsList():Array
		{
			return _materialList;
		}
		
		public static function get totalBytesLoaded():Number
		{
			var n:Number = 0;
			for(var i:Number =0; i<_materialList.length; i++)
			{
				n += _materialList[i].bytesLoaded;
			}
			
			return n;
		}
		
		public static function get totalBytesTotal():Number
		{
			var n:Number = 0;
			for(var i:Number =0; i<_materialList.length; i++)
			{
				n += _materialList[i].bytesTotal;
			}
			
			return n;
		}
		
		public static function get filesList():Array
		{
			return _materialList;
		}
		
		public static function get filesLoaded():Array
		{
			var f:Array = new Array();
			for(var i:Number =0; i<_materialList.length; i++)
			{
				if(_materialList[i].loaded)
				{
					f.push(_materialList[i]);
				}
			}
			
			return f;
		}
		
		public static function get filesError():Array
		{
			var f:Array = new Array();
			for(var i:Number =0; i<_materialList.length; i++)
			{
				if(_materialList[i].error)
				{
					f.push(_materialList[i]);
				}
			}
			
			return f;
		}
		
		private static function checkMaterialsLoading():void
		{
			clearTimeout(_timeoutCallBack);
			//
			var b:Boolean = true;
			//
			for(var i:Number =0; i<_materialList.length-1; i++)
			{
				if( !((_materialList[i].loaded && !_materialList[i].error) || (!_materialList[i].loaded && _materialList[i].error)))
				{
					b = false;
					break;
				}
			}
			//
			if(b && callBack != null)
			{
				callBack();
				callBack = null;
				setTimeout(function(){_materialList = new Array();}, 1000);
			}
		}
		
		// call this function after all materials is loaded
		public static function get callBack():Function
		{
			return _allMaterialsLoaded;
		}
		
		public static function set callBack(f:Function):void
		{
			_allMaterialsLoaded = f;
		}
		
	}
}